using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using JGSY.CMS.LowCode.Platform.Domain.Entities;
using JGSY.CMS.LowCode.Platform.Domain.Interfaces;
using System.Linq.Expressions;
using JGSY.CMS.LowCode.Platform.Infrastructure.CmsDbContext;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Repositories
{
    /// <summary>
    /// 团队仓储实现
    /// 提供团队实体的数据访问功能实现，继承基础仓储并扩展团队特有的业务操作
    /// 支持团队的增删改查、成员管理、权限验证等数据持久化操作
    /// </summary>
    public class TeamRepository : Repository<Team>, ITeamRepository
    {
        /// <summary>
        /// 初始化团队仓储实例
        /// </summary>
        /// <param name="context">数据库上下文</param>
        /// <exception cref="ArgumentNullException">当context为null时抛出</exception>
        public TeamRepository(LowCodeDbContext context) : base(context)
        {
        }

        /// <summary>
        /// 异步添加团队实体
        /// 执行团队信息的持久化操作，包括相关验证和数据完整性检查
        /// </summary>
        /// <param name="entity">要添加的团队实体</param>
        /// <returns>已添加的团队实体</returns>
        /// <exception cref="ArgumentNullException">当entity为null时抛出</exception>
        /// <exception cref="InvalidOperationException">当数据操作失败时抛出</exception>
        public override async Task<Team> AddAsync(Team entity)
        {
            return await base.AddAsync(entity);
        }

        /// <summary>
        /// 异步获取团队总数
        /// 统计数据库中所有团队记录的数量
        /// </summary>
        /// <returns>团队总数</returns>
        /// <exception cref="InvalidOperationException">当数据库操作失败时抛出</exception>
        public override async Task<int> CountAsync()
        {
            return await base.CountAsync();
        }

        /// <summary>
        /// 根据条件异步获取团队数量
        /// 根据指定的查询条件统计匹配的团队记录数量
        /// </summary>
        /// <param name="predicate">查询条件表达式</param>
        /// <returns>匹配条件的团队数量</returns>
        /// <exception cref="ArgumentNullException">当predicate为null时抛出</exception>
        /// <exception cref="InvalidOperationException">当数据库操作失败时抛出</exception>
        public override async Task<int> CountAsync(Expression<Func<Team, bool>> predicate)
        {
            return await base.CountAsync(predicate);
        }

        /// <summary>
        /// 异步删除团队实体
        /// 根据团队实体执行删除操作，支持软删除策略
        /// </summary>
        /// <param name="entity">要删除的团队实体</param>
        /// <returns>删除操作的异步任务</returns>
        /// <exception cref="ArgumentNullException">当entity为null时抛出</exception>
        /// <exception cref="InvalidOperationException">当删除操作失败时抛出</exception>
        public override async Task DeleteAsync(Team entity)
        {
            await base.DeleteAsync(entity);
        }

        /// <summary>
        /// 根据ID异步删除团队
        /// 根据团队ID执行删除操作，支持软删除策略
        /// </summary>
        /// <param name="id">团队ID</param>
        /// <returns>删除操作的异步任务</returns>
        /// <exception cref="ArgumentNullException">当id为null时抛出</exception>
        /// <exception cref="InvalidOperationException">当删除操作失败时抛出</exception>
        public override async Task DeleteAsync(object id)
        {
            await base.DeleteAsync(id);
        }

        /// <summary>
        /// 检查团队是否存在
        /// 根据指定条件验证是否存在匹配的团队记录
        /// </summary>
        /// <param name="predicate">查询条件表达式</param>
        /// <returns>如果存在匹配的团队返回true，否则返回false</returns>
        /// <exception cref="ArgumentNullException">当predicate为null时抛出</exception>
        /// <exception cref="InvalidOperationException">当数据库操作失败时抛出</exception>
        public override async Task<bool> ExistsAsync(Expression<Func<Team, bool>> predicate)
        {
            return await base.ExistsAsync(predicate);
        }

    public override async Task<List<Team>> FindAsync(Expression<Func<Team, bool>> predicate)
        {
            return await base.FindAsync(predicate);
        }

    public override async Task<Team?> FindSingleAsync(Expression<Func<Team, bool>> predicate)
        {
            return await base.FindSingleAsync(predicate);
        }

        public async Task<List<Team>> GetActiveTeamsAsync()
        {
            return await _context.Teams
                .Where(x => x.Status == 1) // 1 = 活跃
                .OrderBy(x => x.Name)
                .ToListAsync();
        }

    public override async Task<Team?> GetByIdAsync(object id)
        {
            return await base.GetByIdAsync(id);
        }

        public async Task<Team?> GetByNameAsync(string name)
        {
            return await _context.Teams
                .FirstOrDefaultAsync(x => x.Name == name && x.Status == 1);
        }

        public async Task<int> GetMemberCountAsync(long teamId)
        {
            return await _context.TeamMembers
                .CountAsync(x => x.TeamId == teamId && x.Status == 1);
        }

    public override async Task<(List<Team> Items, int Total)> GetPagedAsync(int pageIndex, int pageSize, Expression<Func<Team, bool>>? predicate = null)
        {
            return await base.GetPagedAsync(pageIndex, pageSize, predicate);
        }

        public async Task<List<Team>> GetUserTeamsAsync(long userId)
        {
            return await _context.Teams
                .Where(x => x.TeamMembers.Any(m => m.UserId == userId && m.Status == 1) && x.Status == 1)
                .OrderBy(x => x.Name)
                .ToListAsync();
        }

        public async Task<bool> IsNameExistsAsync(string name, long? excludeId = null)
        {
            var query = _context.Teams.Where(x => x.Name == name && x.Status == 1);
            
            if (excludeId.HasValue)
            {
                query = query.Where(x => x.Id != excludeId.Value);
            }
            
            return await query.AnyAsync();
        }

    public override async Task<int> SaveChangesAsync()
        {
            return await base.SaveChangesAsync();
        }

        async Task<List<Team>> IRepository<Team>.GetAllAsync()
        {
            return await base.GetAllAsync();
        }
    }
}
